package main

import (
	"context"
	"fmt"
	"net"
	"os"
	"os/signal"
	"syscall"

	aiv1 "github.com/devops-smartbot/devops-smartbot/proto/gen/go/ai/v1"
	sharedconfig "github.com/devops-smartbot/devops-smartbot/shared/config"
	"github.com/devops-smartbot/devops-smartbot/shared/logger"
	"github.com/devops-smartbot/devops-smartbot/services/ai-gateway/internal/config"
	"github.com/devops-smartbot/devops-smartbot/services/ai-gateway/internal/grpc"
	"github.com/devops-smartbot/devops-smartbot/services/ai-gateway/internal/provider"
	"github.com/devops-smartbot/devops-smartbot/services/ai-gateway/internal/service"
	"go.uber.org/zap"
	"google.golang.org/grpc"
)

func main() {
	cfg := sharedconfig.MustLoad(os.Getenv("CONFIG_FILE"))
	log, err := logger.Init(cfg.App.Name, cfg.App.LogLevel)
	if err != nil {
		panic(fmt.Errorf("logger init: %w", err))
	}
	defer log.Sync() //nolint:errcheck

	serviceCfg := config.FromShared(cfg)

	providers := provider.Registry{
		provider.TypeOpenAI: provider.NewOpenAIProvider(serviceCfg.AI.OpenAIKey),
		provider.TypeOllama: provider.NewOllamaProvider(serviceCfg.AI.OllamaHost),
	}

	aiService := service.New(providers)

	server := grpc.NewServer()
	aiv1.RegisterAIGatewayServer(server, grpcserver.New(aiService))

	lis, err := net.Listen("tcp", fmt.Sprintf(":%d", serviceCfg.GRPCPort))
	if err != nil {
		log.Fatal("failed to listen", zap.Error(err))
	}

	ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
	defer stop()

	go func() {
		log.Info("ai-gateway listening", zap.Int("port", serviceCfg.GRPCPort))
		if err := server.Serve(lis); err != nil {
			log.Fatal("grpc serve failed", zap.Error(err))
		}
	}()

	<-ctx.Done()
	log.Info("shutting down ai-gateway")
	server.GracefulStop()
}
